package com.atguigu.ggkt.vod.service.impl;

import com.atguigu.ggkt.exception.GgktException;
import com.atguigu.ggkt.model.vod.Video;
import com.atguigu.ggkt.utils.LogTool;
import com.atguigu.ggkt.vod.service.VideoService;
import com.atguigu.ggkt.vod.service.VodService;
import com.atguigu.ggkt.vod.utils.ConstantPropertiesUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.vod.v20180717.VodClient;
import com.tencentcloudapi.vod.v20180717.models.DeleteMediaRequest;
import com.tencentcloudapi.vod.v20180717.models.DeleteMediaResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
public class VodServiceImpl implements VodService {

    @Autowired
    private VideoService videoService;

    @Value("${tencent.video.appid}")
    private String appId;
    /**
     *上传视频
     * https://cloud.tencent.com/document/product/266/10276
     */
    @Override
    public String updateVideo(MultipartFile file) {
        //指定当前腾讯云账号id和key
        VodUploadClient client = new VodUploadClient(ConstantPropertiesUtil.SECRET_ID,
                                                     ConstantPropertiesUtil.SECRET_KEY);
        //上传请求对象
        VodUploadRequest request = new VodUploadRequest();
       
        try {
            //获取上传文件输入流
            InputStream inputStream = file.getInputStream();
            String path = "./"+file.getOriginalFilename();
            this.saveToFile(inputStream, path);
            //设置视频文件在本地路径
//            request.setMediaFilePath("D:\\downloads\\futangdaohuo.mp4");
            request.setMediaFilePath(path);
            //任务流
            request.setProcedure("LongVideoPreset");
            //调用方法上传视频，指定地域
            VodUploadResponse response = client.upload(ConstantPropertiesUtil.REGION, request);
            //获取上传之后视频id
            String fileId = response.getFileId();
            LogTool.info(this.getClass(), request.getMediaFilePath()+": "+fileId);
            return fileId;
        } catch (Exception e) {
            // 业务方进行异常处理
            throw new GgktException(20001,"上传视频失败");
        }
    }

    public void saveToFile(InputStream inStream, String outputPath) throws IOException {
        OutputStream outStream = new FileOutputStream(outputPath);
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, bytesRead);
        }
        inStream.close();
        outStream.close();
    }

    /**
     * 删除腾讯云视频
     */
    @Override
    public void removeVideo(String fileId) {
        try{
            // 实例化一个认证对象，入参需要传入腾讯云账户secretId，secretKey
            Credential cred = new Credential(ConstantPropertiesUtil.SECRET_ID,
                                             ConstantPropertiesUtil.SECRET_KEY);
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("vod.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            VodClient client = new VodClient(cred, ConstantPropertiesUtil.REGION, clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            DeleteMediaRequest req = new DeleteMediaRequest();
            req.setFileId(fileId);
            // 返回的resp是一个DeleteMediaResponse的实例，与请求对象对应
            DeleteMediaResponse resp = client.DeleteMedia(req);
            // 输出json格式的字符串回包
            System.out.println(DeleteMediaResponse.toJsonString(resp));
        } catch (TencentCloudSDKException e) {
            System.out.println(e.toString());
            throw new GgktException(20001,"删除视频失败");
        }
    }

    //点播视频播放接口
    @Override
    public Map<String, Object> getPlayAuth(Long courseId, Long videoId) {
        //根据小节id获取小节对象，获取腾讯云视频id
        Video video = videoService.getById(videoId);
        if(video == null) {
            throw new GgktException(20001,"小节信息不存在");
        }

        Map<String, Object> map = new HashMap<>();
        map.put("videoSourceId",video.getVideoSourceId());
        map.put("appId",appId);
//        String psign = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHBJZCI6MTMxNzEyMDMyMywiZmlsZUlkIjoiMTI1MzY0MjcwMDgyMjk3NzA5MSIsImN1cnJlbnRUaW1lU3RhbXAiOjE3MjA3OTU2NzEsImNvbnRlbnRJbmZvIjp7ImF1ZGlvVmlkZW9UeXBlIjoiVHJhbnNjb2RlIiwidHJhbnNjb2RlRGVmaW5pdGlvbiI6MTAxMDQwfSwidXJsQWNjZXNzSW5mbyI6eyJkb21haW4iOiIxMzE3MTIwMzIzLnZvZC1xY2xvdWQuY29tIiwic2NoZW1lIjoiSFRUUFMifX0.dkZoXoWT6TFm_kXZdYaCwgWPc5g7JFQmCWsAcrlx5vA";
        String psign = this.getPsign(Integer.valueOf(appId), video.getVideoSourceId());
        map.put("psign",psign);
        return map;
    }

    /**
     *
     * @param AppId 用户 appid
     * @param FileId 目标 FileId
     * @return
     */
    @Override
    public String getPsign(Integer AppId, String FileId) {
        Integer nowTIME= Math.toIntExact(System.currentTimeMillis() / 1000);
        System.out.println("nowTIME" + nowTIME);
//        Integer AppId = 1317120323;
//        String FileId = FileId;//"1253642700822977091";
        Integer CurrentTime = nowTIME;
        Integer PsignExpire = nowTIME+(60*30);
        String UrlTimeExpire = "62ce5213";
        String AudioVideoType = "Transcode";
        Integer TranscodeDefinition=100010;

        String Key = "vOsXn0ZiC3H8D6MPZdWX";
        HashMap urlAccessInfo = new HashMap<>();
        urlAccessInfo.put("t", UrlTimeExpire);
        HashMap<String, Object> contentInfo = new HashMap<String, Object>();
        contentInfo.put("audioVideoType", AudioVideoType);
        contentInfo.put("transcodeDefinition",TranscodeDefinition);
        String token = null;
        try {
            Algorithm algorithm = Algorithm.HMAC256(Key);
            token = JWT.create().withClaim("appId", AppId)
                    .withClaim("fileId", FileId)
                    .withClaim("contentInfo", contentInfo)
                    .withClaim("currentTimeStamp", CurrentTime).sign(algorithm);
            System.out.println("token:" + token);
        } catch (JWTCreationException exception) {
            exception.printStackTrace();
        }
        return token;
    }

    /**
     *
     * @param AppId 用户 appid
     * @param FileId 目标 FileId
     * @return
     */
//    @Override
    public String getPsign2(Integer AppId, String FileId) {
        String AudioVideoType = "Transcode"; // 播放的音视频类型
        Integer RawAdaptiveDefinition = 10; // 允许输出的未加密的自适应码流模板 ID
        Integer ImageSpriteDefinition = 10; // 做进度条预览的雪碧图模板 ID
        Integer CurrentTime = Math.toIntExact((System.currentTimeMillis() / 1000));
//        Integer PsignExpire = 1589548067; // 可任意设置过期时间
//        String UrlTimeExpire = "5ebe9423‬"; // 可任意设置过期时间
        String PlayKey = "vOsXn0ZiC3H8D6MPZdWX";
        HashMap<String, Object> urlAccessInfo = new HashMap<String, Object>();
        urlAccessInfo.put("domain", "1317120323.vod-qcloud.com");
        urlAccessInfo.put("scheme", "HTTPS");
        HashMap<String, Object> contentInfo = new HashMap<String, Object>();
        contentInfo.put("audioVideoType", AudioVideoType);
//        contentInfo.put("rawAdaptiveDefinition", RawAdaptiveDefinition);
//        contentInfo.put("imageSpriteDefinition", ImageSpriteDefinition);
        contentInfo.put("transcodeDefinition", "101040");

        String token = null;
        try {
            Algorithm algorithm = Algorithm.HMAC256(PlayKey);
            token = JWT.create().withClaim("appId", AppId).withClaim("fileId", FileId)
                    .withClaim("contentInfo", contentInfo)
                    .withClaim("currentTimeStamp", CurrentTime)
//                    .withClaim("expireTimeStamp", PsignExpire)
                    .withClaim("urlAccessInfo", urlAccessInfo)
                    .sign(algorithm);
            System.out.println("token:" + token);
        } catch (JWTCreationException exception) {
            // Invalid Signing configuration / Couldn't convert Claims.
            exception.printStackTrace();
        }

        return token;
    }
}
